﻿using System;
using System.Collections.Concurrent;
using System.Linq;
using System.Threading;
using TitaniumAS.Opc.Client.Common;
using TitaniumAS.Opc.Client.Da;
using static MolyMart.Utils;

namespace MolyMart.WithOPC
{
    public class ConnectonWorker
    {
        private readonly BlockingCollection<OpcServer> _blockingQuietQueue;
        private readonly BlockingCollection<OpcServer> _blockingActiveQueue;
        private readonly BlockingCollection<MessageItem> _messageQueue;

        public ConnectonWorker(BlockingCollection<OpcServer> quietQueue, BlockingCollection<OpcServer> activeQueue, BlockingCollection<MessageItem> messageQueue)
        {
            _blockingQuietQueue= quietQueue;
            _blockingActiveQueue = activeQueue;
            _messageQueue = messageQueue;
        }
        public void Run()
        {
            while (true)
            {
                var aServer = _blockingQuietQueue.Take();
                if (aServer.OpcDaServer!=null&&aServer.OpcDaServer.IsConnected)
                {
                    _blockingActiveQueue.Add(aServer);
                }
                else
                {
                    OpcServer connectedServer = ConnectServer(aServer);
                    _blockingActiveQueue.Add(connectedServer);
                    _messageQueue.Add(Log($"ConnectionWorker{this.GetHashCode()}","Added to Queue"));
                }
                Thread.Sleep(1000);
            }
        }

        private OpcServer ConnectServer(OpcServer opcServer)
        {
            OpcServer connectedServer = new OpcServer {OpcServerDefinition = opcServer.OpcServerDefinition};
            var url = UrlBuilder.Build(opcServer.OpcServerDefinition.ServerName, opcServer.OpcServerDefinition.HostName);
            connectedServer.OpcDaServer = new OpcDaServer(url);
            connectedServer.OpcDaServer.Connect();//TODO:Try here.
            connectedServer.ServerState = ServerState.Connected;
            connectedServer.OpcDaGroup = connectedServer.OpcDaServer.AddGroup("MolyAddedGroup");
            connectedServer.OpcDaGroup.IsActive = true;
            connectedServer.OpcDaItemDefinitions = opcServer.OpcServerDefinition.Items.Select(i => new OpcDaItemDefinition()
            {
                ItemId = i.Item,
                IsActive = true
            }).ToArray();
            connectedServer.LastTryConnectTime = Utils.GetUnixTimeStamp();
            connectedServer.OpcDaItemResults = connectedServer.OpcDaGroup.AddItems(connectedServer.OpcDaItemDefinitions);
            connectedServer.ServerState = ServerState.ItemsAdded;
            connectedServer.LastConnectTime = Utils.GetUnixTimeStamp();
            return connectedServer;
        }
    }
}
